<!DOCTYPE html>
<html>
<head>
	<title>OpenError - histogram of distances</title>
	<script type="text/javascript" src="../js/sparklines.min.js"></script>
	<script type="text/javascript" src="../js/openerror-v1.0.min.js"></script>
	<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
	<script type="text/javascript">
	// GLOBALS / CONFIG DATA
	var oe;
	var map;
	
	var origin = {"coordinates":[42.73342147048282, -84.55609416961669]};
	var largerMapSize = {'width':1024, 'height':768};
	var origin_marker;
	var offset_marker;
	var histogram_object;
	var data;
	var sparkline_object;
	var drawCount = 0;
	
	// Histogram object
	function Histogram()
	{
		this.distances = [];
		this.bucketSize = null;
		
	}
	Histogram.prototype.minVal = function(histogram) {
		if(histogram.length < 1) {
			throw new Error("minVal function called with invalid histogram.");
		}
		var min = histogram[0];
		for(var i=1;i<histogram.length;i++) {
			if( histogram[i] < min) {
				min = histogram[i];
			}
		}
		return min;
	};
	Histogram.prototype.maxVal = function(histogram) {
		if(histogram.length < 1) {
			throw new Error("maxVal function called with invalid histogram.");
		}
		var max = histogram[0];
		for(var i=1;i<histogram.length;i++) {
			if( histogram[i] > max) {
				max = histogram[i];
			}
		}
		return max;
	};
	Histogram.prototype.createHistogram = function()
	{
		if(this.bucketSize == null)
			return;
		
		var histogram = [0,0,0,0,0];
		for(var i=0;i<this.distances.length;i++)
		{
			var dist = this.distances[i];
			if(dist < this.bucketSize)
			{
				histogram[0]++;
			}
			else if(dist < (this.bucketSize * 2))
			{
				histogram[1]++;
			}
			else if(dist < (this.bucketSize * 3))
			{
				histogram[2]++;
			}
			else if(dist < (this.bucketSize * 4))
			{
				histogram[3]++;
			}
			else if(dist < (this.bucketSize * 5))
			{
				histogram[4]++;
			}
		}
		
		return histogram;
	}
	
	
	function init() {
		// create the google map
		var myOptions = {
		  zoom: 15,
		  mapTypeId: google.maps.MapTypeId.ROADMAP,
		  center: new google.maps.LatLng(origin.coordinates[0], origin.coordinates[1])
		}
		map = new google.maps.Map(document.getElementById("map"), myOptions);
		
		// create the marker
		origin_marker = new google.maps.Marker({  
  			position: new google.maps.LatLng(origin.coordinates[0], origin.coordinates[1]),  
  			map: map
		});
		
		histogram_object = new Histogram();
		histogram_object.bucketSize = 1;
		
		//var errorControl = new MyControl(controlDiv);

		
		google.maps.event.addDomListener(document.getElementById('randomize'), 'click', function() {
			generateNewPoint();
		});
		

		// create and configure the openerror object
		oe = new OpenError();
		oe.setDebug(false);
		oe.setK(3);
		oe.setStandardDeviation(90);
		
		var controlDiv = document.createElement('DIV');
		var mc = document.getElementById('mapControl');
		controlDiv.appendChild(mc);
		map.controls[google.maps.ControlPosition.TOP_CENTER].push(controlDiv);
		
	}
	
	// Create a new random point, adjust all visualizations
	function generateNewPoint(){
		// remove the old marker if it exists
		if(typeof offset_marker !== "undefined")
		{
			offset_marker.setMap(null);
		}
		
		
		var point = oe.Random.boxMuller();
		var distance = Math.sqrt( (point.coordinates[0]*point.coordinates[0]) + (point.coordinates[1]*point.coordinates[1]));
		point.scale(origin.coordinates[0], oe.getStandardDeviation(), oe.getUnits());
		var image = "../img/blue_marker.png";
		offset_marker = new google.maps.Marker({  
  			position: new google.maps.LatLng(origin.coordinates[0]+point.coordinates[0], origin.coordinates[1]+point.coordinates[1]),  
  			map: map,
  			icon: image
		});
		
		document.getElementById("pointText").innerHTML = (origin.coordinates[0]+point.coordinates[0]) + ", " + (origin.coordinates[1]+point.coordinates[1]);
		histogram_object.distances.push(distance);
		data = histogram_object.createHistogram();
		var opts = {'scale_from':undefined, "background":"#ffffff", "stroke":"#3840B5",
					'bottom-padding':0,'top-padding':0, 'scale_from':undefined,'scale_to':undefined,'left-padding':0,'right-padding':0};
		
		
		// the sparkline library seems to get offset from the left on each draw() call (i.e. the whole chart slide to the right and down by a pixel on each draw)
		// I had to create a new canvas element in order to get each new draw() to appear correctly
		var old_canvas = geo$('sparkline');
		var canvas = document.createElement('CANVAS');
		canvas.id = 'sparkline';
		canvas.style.width = '300px';
		canvas.style.height = '19px';
		geo$('canvasHolder').appendChild(canvas);
		old_canvas.parentElement.removeChild(old_canvas);
		
		
		sparkline_object = new BarSparkline("sparkline",data,opts);
		sparkline_object.draw();
		geo$('nValue').innerHTML = (++drawCount) +"";
	}
	
	geo$ = function(id) { return document.getElementById(id); };
	function toggleMapSize() {
		var mp = geo$('map');
		if(mp.style.width == '640px') {
			mp.style.width = largerMapSize.width+"px";
			mp.style.height = largerMapSize.height+"px";
			google.maps.event.trigger(map, "resize");
			geo$('mapSizeToggle').value = 'Shrink Map';
		} else {
			mp.style.height = '480px';
			mp.style.width = '640px';
			google.maps.event.trigger(map, "resize");
			geo$('mapSizeToggle').value = 'Enlarge Map';
		}
	}
	</script>
</head>
<body onload="init()">
<h2>Generate Random Points and plot on Sparkline</h2>
<p>Generate a new point using the box muller function and add the x value to a list of data points. It then plots the sparkline.</p>

<input type="button" id="mapSizeToggle" value="Enlarge Map" onclick="toggleMapSize()" />New Point: <span id="pointText">null</span>
<div>
	
	<div id="map" style="width:640px;height: 480px;border: 1px solid black;float: left;"></div>
	
	<!-- start map control -->
	<!-- NOTE - this element is removed immediately from it's current position, and placed within the google maps heirarchy -->
	<div id="mapControl" style="margin:0;margin-top: 5px;font-size: 12px;font-family:arial;border: 1px solid #9ebae8;background: white;">
		<table style="background: white;border-collapse:collapse;border-spacing:0;padding:0;margin:0;">
			<tr>
				<td>(n=<span id="nValue">0</span>)</td>
				<td id="canvasHolder"><canvas id="sparkline" style="width: 300px; height: 19px;"></canvas></td>
				<td style="border-left: 1px solid #9ebae8;vertical-align:middle"><div id="randomize" style="display:inline-block;height:19px;margin:0;padding-left: 1em; padding-right: 1em;cursor:pointer;">Randomize</div></td>
			</tr>
		</table>
	</div>
	<!-- end map control -->
</div>
</body>
</html>